#include "stdafx.h"
#include "thread_context.h"
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>

typedef struct thread_context
{
	pthread_mutex_t		lock;
	uint32_t			freeflag;
	uint32_t			initflag;
	int					sockfd[32];
	MYSQL				mysql[32];
} thread_context_t;

// 申名全局变量
static thread_context_t		thread_context		= {0};

/*
 * 初始化操作
 */
void thread_context_init(int max)
{
	int			i;

	for(i = 0; i < max && i < 32; i++)
	{
		// 设置标志
		thread_context.freeflag |= (0x1 << i);
		// 初始化网络
		thread_context.sockfd[i] = socket(AF_INET, SOCK_DGRAM, 0);
	}
	
	pthread_mutex_init(&thread_context.lock, NULL);
}

/*
 * 获取MYSQL连接
 */
bool thread_context_get(MYSQL** mysql, int* fd)
{
	int			id		= -1;
	int			i;
	char		szhost[128]		= {0};
	char		szuser[128]		= {0};
	char		szpwd[128]		= {0};
	char		szdb[128]		= {0};

	pthread_mutex_lock(&thread_context.lock);
	for(i = 0; i < 32; i++)
	{
		if( 0 != ((0x1 << i) & thread_context.freeflag) )
		{
			id = i;
			thread_context.freeflag &= ~(0x1 << i);
			break;
		}
	}

	pthread_mutex_unlock(&thread_context.lock);
	if(id < 0 || id > 31)
	{
		return false;
	}
	// 返回连接成功的MYSQL
	if( 0 != ((0x1 << id) & thread_context.initflag)
			&& 0 == mysql_ping(&thread_context.mysql[id]) )
	{
		*mysql = &thread_context.mysql[id];
		*fd = thread_context.sockfd[id];
		return true;
	}
	// 新连接数据库
	mysql_init(&thread_context.mysql[id]);

	ini_get_mysql_host(szhost, sizeof(szhost) - 1);
	ini_get_mysql_user(szuser, sizeof(szuser) - 1);
	ini_get_mysql_pwd(szpwd, sizeof(szpwd) - 1);
	ini_get_mysql_database(szdb, sizeof(szdb) - 1);

	if( !mysql_real_connect(&thread_context.mysql[id], szhost, szuser, szpwd, szdb
					, 0, NULL, CLIENT_FOUND_ROWS) )
	{
		syslog(LOG_ERR, "mysql_real_connet failed: %s"
					, mysql_error(&thread_context.mysql[id]));
		return false;
	}

	*mysql = &thread_context.mysql[id];
	*fd = thread_context.sockfd[id];	
	thread_context.initflag |= (0x1 << id);
	return true;
}

/*
 * 释放操作
 */
void thread_context_free(MYSQL* mysql, int fd)
{
	int			i;

	pthread_mutex_lock(&thread_context.lock);
	for(i = 0; i < 32; i++)
	{
		if( mysql == &thread_context.mysql[i]
				|| fd == thread_context.sockfd[i])
		{
			thread_context.freeflag |= (0x1 << i);
			break;
		}
	}

	pthread_mutex_unlock(&thread_context.lock);

}
